package org.iot.iotserver.netty.config;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelId;
import io.netty.channel.SimpleChannelInboundHandler;
import org.iot.iotserver.service.IIOTCommonService;

public class AbstractIOTServerHandler extends SimpleChannelInboundHandler<String> {

    private static final Log log = LogFactory.get();

    private final IIOTCommonService iotCommonService;

    public AbstractIOTServerHandler(IIOTCommonService iotCommonService) {
        this.iotCommonService = iotCommonService;
    }

    /**
     * 校验上送的文本信息
     */
    protected boolean validation(String s) {
        return true;
    }

    /**
     * 获取参数
     * @param receiveData
     * @return
     */
    protected String getCommandName(String receiveData) {
        return receiveData.split("\\s+")[0];
    }

    /**
     * 获取参数
     * @param receiveData
     * @return
     */
    protected String[] getArgs(String receiveData) {
        String[] args = ArrayUtil.remove(receiveData.split("\\s+"), 0);
        return args;
    }

    /**
     * 当有客户端连接时，handlerAdded会执行,就把该客户端的通道记录下来，加入队列
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        ChannelId id = channel.id();
        log.info("新客户端加入: [{}]", id.asShortText());
        //加入队列
        this.iotCommonService.addChannel(channel);
    }

    /**
     * 断开连接
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        //获得客户端通道
        Channel channel = ctx.channel();
        String deviceName = (String) channel.attr(NettyConstant.DEVICE_KEY).get();

        if(deviceName != null) {
            NettyConstant.DEVICE_CACHE.get(deviceName).setStatus(NettyConstant.DeviceStatus.IN_ACTIVE);
        }

        ChannelId id = channel.id();
        log.info("客户端 [{}] 退出", id.asShortText());
        this.iotCommonService.removeChannel(id);
    }

    /**
     * 当服务器监听到客户端活动时
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel inComing = ctx.channel();
        log.info("[{}]: 在线", inComing.remoteAddress());
        log.info("当前客户端数量: {}", iotCommonService.getChannelSize());
    }

    /**
     * 离线
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel inComing = ctx.channel();
        log.info("[{}]: 离线", inComing.remoteAddress());
        log.info("当前客户端数量: {}", iotCommonService.getChannelSize());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Channel inComing = ctx.channel();
        log.info("[{}]: 发生异常", inComing.remoteAddress());
        ctx.close();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

    }
}
